/*
 * Copyright 2025 arisgo@163.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.arisgo.cloud.attendance.clazz.service.impl;

import com.arisgo.cloud.attendance.clazz.core.Arrange;
import com.arisgo.cloud.attendance.clazz.core.ArrangeContext;
import com.arisgo.cloud.attendance.clazz.core.arrange.ArrangeStore;
import com.arisgo.cloud.attendance.clazz.core.arrange.TemporaryArrange;
import com.arisgo.cloud.attendance.clazz.entity.ClassInfo;
import com.arisgo.cloud.attendance.clazz.entity.ClassShift;
import com.arisgo.cloud.attendance.clazz.mapper.ClassInfoMapper;
import com.arisgo.cloud.attendance.clazz.mapper.ClassSegmentMapper;
import com.arisgo.cloud.attendance.clazz.mapper.ClassShiftMapper;
import com.arisgo.cloud.attendance.clazz.mapper.StaffClassMapper;
import com.arisgo.cloud.attendance.clazz.service.ClassInfoService;
import com.arisgo.cloud.attendance.clazz.vo.ClassInfoDetailVo;
import com.arisgo.cloud.attendance.clazz.vo.ClassInfoVo;
import com.arisgo.cloud.attendance.clazz.vo.ClassSegmentVo;
import com.arisgo.cloud.attendance.clazz.vo.TemporaryClassVo;
import com.arisgo.cloud.attendance.clazz.vo.TemporaryArrangeVo;
import com.arisgo.cloud.common.utils.AssertUtil;
import com.arisgo.cloud.common.utils.DateUtil;
import com.arisgo.cloud.web.mybatis.service.CloudServiceImpl;
import com.arisgo.cloud.web.utils.RequestUtil;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 班
 *
 * @author Coulson
 * @since 2024-12-31
 */
@Slf4j
@Service
@AllArgsConstructor
public class ClassInfoServiceImpl extends CloudServiceImpl<ClassInfoMapper, ClassInfo, ClassInfoVo> implements ClassInfoService {

    private final ClassShiftMapper classShiftMapper;
    private final ClassSegmentMapper classSegmentMapper;
    private final StaffClassMapper staffClassMapper;

    @Override
    public ClassInfo getInstanceModel() {
        return new ClassInfo();
    }

    @Override
    public ClassInfoVo getInstanceVo() {
        return new ClassInfoVo();
    }

    private final ArrangeStore store;

    @Override
    public List<ClassInfoDetailVo> findByStaffId(Long tenantId, Long staffId, LocalDate startDate, LocalDate endDate) {
        if (null == startDate || null == endDate) {
            startDate = DateUtil.convertDate(DateUtil.monthFirstDay(null));
            endDate = DateUtil.convertDate(DateUtil.monthLastDay(null));
        }
        return this.mapper.findByStaffId(tenantId, staffId, startDate, endDate);
    }

    @Override
    public List<ClassInfoDetailVo> findClassInfo(Long tenantId, LocalDate startDate, LocalDate endDate) {
        if (null == startDate || null == endDate) {
            startDate = DateUtil.convertDate(DateUtil.monthFirstDay(null));
            endDate = DateUtil.convertDate(DateUtil.monthLastDay(null));
        }
        return this.mapper.findClassInfo(tenantId, startDate, endDate);
    }

    @Override
    public List<ClassInfoDetailVo> findClassDetail(Long tenantId, LocalDate workday) {
        return this.mapper.findClassDetail(tenantId, workday);
    }

    @Override
    public boolean removeClassInfo(Long classId) {
        // 删除与班关联的员工
        staffClassMapper.deleteByClassInfoIds(RequestUtil.getTenantId(), Lists.newArrayList(classId));
        // 删除班信息
        this.mapper.deleteById(classId);
        return true;
    }

    @Override
    public boolean removeClassInfo(List<Long> classIds) {
        // 删除与班关联的员工
        staffClassMapper.deleteByClassInfoIds(RequestUtil.getTenantId(), classIds);
        // 删除班信息
        this.mapper.deleteBatchByIds(classIds);
        return true;
    }

    @Override
    public boolean arrange(String type, ArrangeContext context) {
        AssertUtil.isTrue(store.contains(type), "不支持的排班类型! type: " + type);
        Arrange arrange = store.get(type);
        // 数据校验
        arrange.validate(context);
        // 排班
        log.info("type tenantId: {}", context.getTenantId());
        arrange.arrange(context);
        // TODO 异步处理
//        CompletableFuture.runAsync(() -> arrange.arrange(context));
        return true;
    }

    @Override
    public boolean arrange(TemporaryArrangeVo vo) {
        AssertUtil.notNull(vo, "参数为空！");
        ArrangeContext context = new ArrangeContext();
        context.setTenantId(RequestUtil.getTenantId());
        context.setStaffIds(Lists.newArrayList(vo.getStaffId()));

        ClassShift classShift = classShiftMapper.selectOneById(vo.getShiftId());
        TemporaryClassVo shift = new TemporaryClassVo();
        BeanUtils.copyProperties(classShift, shift);
        context.setTemporaryClass(shift);

        List<ClassSegmentVo> segments = classSegmentMapper.findByShiftIds(Lists.newArrayList(vo.getShiftId()));
        AssertUtil.notEmpty(segments, "班段不存在！");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
        shift.setStartTime(segments.get(0).getStartTime().format(formatter));
        shift.setEndTime(segments.get(0).getEndTime().format(formatter));

        context.setWorkdays(Lists.newArrayList(vo.getWorkday()));
        return store.get(TemporaryArrange.KEY).arrange(context);
    }

}
